/****************************************************************
 ** Product  :   HP Subscriber Network Application Policy
 ** Module   :   gr-manager
 ** Date: Apr 10, 2015               
 ** Author: Huang xiaoji
 ** (C) Copyright 2015, Hewlett-Packard Company, All Rights Reserved.
 ** This software is the proprietary information of HP, Inc.  
 ** Use is subject to license terms.
 *****************************************************************
 ** Description:   
 **     Compress the program files.
 **    
 ****************************************************************/
package com.hp.snap.gr.action.impl;

import com.hp.snap.gr.exception.ActionException;
import com.hp.snap.gr.model.jaxb.ActionType;
import com.hp.snap.gr.utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.FileSystemUtils;

import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 
 * Compress the program files. Compress all host program files in current site to a ProgramFiles.zip file and placed it
 * work/exportTarget folder.
 * 
 * The action have no parameter need to be configured.
 * 
 * <P>
 * Version: 3.3 <br>
 * Author: Huang xiaoji Date: Apr 10, 2015
 * 
 * </P>
 * 
 **/
public class CompressProgramFilesActionHandler extends AbstractActionHandler {
    private static final Logger logger = LoggerFactory.getLogger(CompressProgramFilesActionHandler.class);

    private SSHTools ssh = new SSHTools(null, null);

    @Override
    public void execute(ActionType action, Map<String, Object> actionPlanInputs, Map<String, Object> actionPlanOutputs) throws ActionException {
        //backup files in every hosts
        Map<String, Map<String, Object>> hosts = Utils.getAllHostsInSite(GRMConfigManager.getSiteName());
        if (hosts == null) {
            throw new ActionException("CompressProgramFilesActionHandler get configuration data failed");
        }
        Set<String> compressedPaths = new HashSet<String>();
        File destination = new File(Constants.USER_GR_TEMP, "C" + System.currentTimeMillis());
        destination.mkdirs();

        try {
            for (Map.Entry<String, Map<String, Object>> entry : hosts.entrySet()) {
                if (logger.isTraceEnabled()) {
                    logger.trace("processing host {} ...", entry.getKey());
                }
                Map<String, Object> map = entry.getValue();
                String hostIp = (String) map.get("HOST_IP");
                String[] files = (String[]) map.get("FILES");
                if (logger.isTraceEnabled()) {
                    logger.trace("host ip {} files {}", hostIp, Arrays.toString(files));
                }
                if (files != null && files.length > 0) {
                    for (String file : files) {
                        if (compressedPaths.contains(file)) {
                            if (logger.isTraceEnabled()) {
                                logger.trace("file {} has been compressed", file);
                            }
                        } else {
                            compressPath(hostIp, file, destination.getAbsolutePath());
                            compressedPaths.add(file);
                        }
                    }
                    try {
                        CmdUtils.runShellScript("cd " + destination + "; zip -r " + Constants.USER_GR_WORK + "/exportTarget/ProgramFiles.zip *");
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                        throw new ActionException(e);
                    }
                }
            }
        } finally {
            if (logger.isTraceEnabled()) {
                logger.trace("skip to delete resource in TRACE mode");
            } else {
                FileSystemUtils.deleteRecursively(destination);
            }
        }
    }

    private void compressPath(String hostIp, String file, String destination) throws ActionException {
        if (logger.isTraceEnabled()) {
            logger.trace("compressing {} on {}", file, hostIp);
        }
        try {
            String filename = "F" + System.currentTimeMillis() + ".zip";
            ssh.cmd(hostIp, "zip -r /tmp/" + filename + " " + file);
            ssh.copyFromRemote(destination + "/" + filename, hostIp, "/tmp/" + filename);

            CmdUtils.runShellScript("unzip -d " + destination + " " + destination + "/" + filename);
            CmdUtils.runShellScript("rm -f " + destination + "/" + filename);

            ssh.cmd(hostIp, "rm -f /tmp/" + filename);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new ActionException(e);
        }
    }
}
